package service

import (
	"bytes"
	"errors"
	"fmt"
	"gin-epg/internal/app/common/page"
	"gin-epg/internal/app/common/util"
	"gin-epg/internal/app/entity"
	"gin-epg/internal/app/mapper"
	"gin-epg/internal/app/param"
	"gin-epg/internal/app/store"
	_ "golang.org/x/image/bmp"  // 导入 BMP 解码器
	_ "golang.org/x/image/tiff" // 导入 TIFF 解码器
	_ "golang.org/x/image/webp" // 导入 WebP 解码器
	"image"
	_ "image/jpeg" // 导入 JPEG 解码器
	"image/png"
	_ "image/png" // 导入 PNG 解码器
	"io"
	"mime/multipart"
)

/*
*
获取epgChannel列表
*/
func GetEpgChannelList(params *param.QueryEpgChannelListParam) (epgChannelList []*entity.EpgChannel, err error) {
	epgChannelList, err = mapper.GetEpgChannelList(params)
	if err != nil {
		return nil, err
	}
	return epgChannelList, nil
}

/*
*
获取epgChannel分页
*/
func GetEpgChannelPage(params *param.QueryEpgChannelPageParam) (page *page.PageResult[entity.EpgChannel], err error) {
	page, err = mapper.GetEpgChannelPage(params)
	if err != nil {
		return nil, err
	}
	return page, nil
}

/*
*
获取epgChannel分页
*/
func GetEpgChannelStd(name string) (string, error) {
	//打印name值
	println("name:", name)
	// 首先尝试通过名称获取 EpgChannel
	channel, err := mapper.GetEpgChannelByName(name)
	if err == nil && channel != nil {
		return channel.Name, nil
	}
	println("查询别名表")
	// 如果通过名称获取失败，再尝试通过别名获取 EpgChannelAlias
	alias, err := mapper.GetEpgChannelAliasByAlias(name)
	if err == nil && alias != nil {
		return alias.Name, nil
	}

	// 如果两者都获取不到结果，返回错误
	return "", errors.New("no channel or alias found")
}

/*
*
根据id查询用户EpgChannel
*/
func GetEpgChannelById(id string) (epgChannel *entity.EpgChannel, err error) {
	epgChannel, err = mapper.GetEpgChannelById(id)
	if err != nil {
		return nil, err
	}
	return epgChannel, nil
}

/*
*
新建EpgChannel信息
*/
func CreateEpgChannel(epgChannel *entity.EpgChannel) (err error) {
	if err = mapper.CreateEpgChannel(epgChannel); err != nil {
		return err
	}
	return
}

/*
*
更新EpgChannel信息
*/
func UpdateEpgChannel(epgChannel *entity.EpgChannel) (err error) {
	err = mapper.UpdateEpgChannel(epgChannel)
	return
}

/*
*
根据id删除epgChannel
*/
func DeleteEpgChannelById(id string) (err error) {
	err = mapper.DeleteEpgChannelById(id)
	return
}

/*
*
根据name删除epgChannel
*/
func DeleteEpgChannelByName(name string) (err error) {
	err = mapper.DeleteEpgChannelByName(name)
	err = mapper.DeleteEpgChannelAliasByAlias(name)
	return
}

// UploadEpgChannelLogoByName 上传频道 Logo 并统一转为 PNG 格式
// 支持png jpg bmp tiff webp 格式
func UploadEpgChannelLogoByName(name string, file *multipart.FileHeader) error {
	// 检查频道名是否为空
	if name == "" {
		return errors.New("频道名不能为空")
	}

	//根据名称查询频道是否存在
	_, err := mapper.GetEpgChannelByName(name)
	if err != nil {
		return fmt.Errorf("failed to find channel by name: %v", err)
	}

	// 打开上传的文件
	src, err := file.Open()
	if err != nil {
		return fmt.Errorf("failed to open uploaded file: %v", err)
	}
	defer src.Close()

	// 读取图像
	img, format, data, err := decodeImage(src, file.Filename)
	if err != nil {
		return err
	}

	var reader io.Reader
	// 如果不是 PNG 格式，则转换为 PNG
	if format != "png" {
		// 创建一个新的内存缓冲区
		buf := new(bytes.Buffer)
		// 将图像以 PNG 格式保存到缓冲区
		if err := png.Encode(buf, img); err != nil {
			return err
		}
		// 重新创建一个 Reader
		reader = bytes.NewReader(buf.Bytes())
	} else {
		// 如果已经是 PNG 格式，直接使用原始的 Reader
		reader = bytes.NewReader(data)
	}

	// 读取 logo 内容
	logoData, err := io.ReadAll(reader)
	if err != nil {
		return fmt.Errorf("failed to read logo data for channel %s: %v", name, err)
	}

	// 将 logo 存储到 OSS
	ossKey := fmt.Sprintf("logo/%s.png", name)
	// 创建 OSS 存储服务实例
	ossService := store.GlobalStoreService
	if err := ossService.Save(ossKey, logoData); err != nil {
		return fmt.Errorf("failed to save logo to OSS for channel %s: %v", name, err)
	}

	// 拼接 fileDownloadUrl 和 filePath
	fileDownloadUrl := "https://your-bucket-name.oss-cn-region.aliyuncs.com/"
	configFileDownloadUrl, err := util.GetConfigValue("fileDownloadUrl")
	if err == nil {
		fileDownloadUrl = configFileDownloadUrl.(string) // 进行类型断言
	}
	logoPath := fileDownloadUrl + ossKey

	// 更新 epg_channel 表的 logo 字段
	err = mapper.UpdateEpgChannelLogoByName(name, logoPath)
	if err != nil {
		return fmt.Errorf("failed to update logo path for channel %s: %v", name, err)
	}

	fmt.Printf("文件 %s 上传成功，保存路径: %s\n", file.Filename, logoPath)
	return nil
}

// decodeImage 读取图像
func decodeImage(r io.Reader, filename string) (image.Image, string, []byte, error) {
	// 读取整个文件内容到内存
	data, err := io.ReadAll(r)
	if err != nil {
		return nil, "", nil, err
	}

	// 重新创建一个 Reader
	reader := bytes.NewReader(data)

	// 读取图像
	img, format, err := image.Decode(reader)
	if err != nil {
		return nil, "", nil, err
	}

	return img, format, data, nil
}
